package com.bonc.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.bonc.datasource.multiple.MultipleDataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * mybatis-plus配置
 * @author jinlong
 */
@Configuration
public class MybatisPlusConfig {



    /**
     * 动态表名
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 分页插件
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
        // 动态表名插件
        DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
        Map<String, TableNameHandler> tableNameHandlerMap = new HashMap<String, TableNameHandler>(1){{
            put("fix_table",( sql,  tableName)->{
                return tableName;
            });
        }};
        dynamicTableNameInnerInterceptor.setTableNameHandlerMap(tableNameHandlerMap);
        mybatisPlusInterceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
        return mybatisPlusInterceptor;
    }



    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(multipleDataSource(db1(),db2(), db3()));
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/**/*.xml"));
        MybatisConfiguration configuration = new MybatisConfiguration();
        //configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        sqlSessionFactory.setConfiguration(configuration);
        sqlSessionFactory.setPlugins(new Interceptor[]{ //PerformanceInterceptor(),OptimisticLockerInterceptor()
                mybatisPlusInterceptor() //添加分页功能
        });
        //sqlSessionFactory.setGlobalConfig(globalConfiguration());
        return sqlSessionFactory.getObject();
    }

    @Bean(name = "mysqldata")
    @ConfigurationProperties(prefix = "spring.datasource.druid.mysqldata" )
    public DataSource db1() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "gbasedata")
    @ConfigurationProperties(prefix = "spring.datasource.druid.gbasedata" )
    public DataSource db2() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "data")
    @ConfigurationProperties(prefix = "spring.datasource.druid.data" )
    public DataSource db3() {
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 动态数据源配置
     * @return
     */
    @Bean
    @Primary
    public DataSource multipleDataSource(@Qualifier("mysqldata") DataSource db1, @Qualifier("gbasedata") DataSource db2, @Qualifier("data") DataSource db3) {
        MultipleDataSource multipleDataSource = new MultipleDataSource();
        Map< Object, Object > targetDataSources = new HashMap<>();
        targetDataSources.put("mysqldata", db1);
        targetDataSources.put("gbasedata", db2);
        targetDataSources.put("data", db3);
        //添加数据源
        multipleDataSource.setTargetDataSources(targetDataSources);
        //设置默认数据源
        multipleDataSource.setDefaultTargetDataSource(db1);
        multipleDataSource.afterPropertiesSet();
        return multipleDataSource;
    }


    // A库事务管理器
    @Bean("primaryTransaction")
    @Primary
    @Qualifier("primaryTransaction")
    public PlatformTransactionManager primaryTransactionManager(@Qualifier("mysqldata") DataSource primaryDataSource) {
        return new DataSourceTransactionManager(primaryDataSource);
    }

    // B库事务管理器
    @Bean("secondaryTransaction")
    @Qualifier("secondaryTransaction")
    public PlatformTransactionManager secondaryManager(@Qualifier("gbasedata") DataSource secondaryDataSource) {
        return new DataSourceTransactionManager(secondaryDataSource);
    }

    // C库事务管理器
    @Bean("secondaryTransaction")
    @Qualifier("secondaryTransaction")
    public PlatformTransactionManager secondaryManager1(@Qualifier("data") DataSource secondaryDataSource1) {
        return new DataSourceTransactionManager(secondaryDataSource1);
    }
}
